import sys
from dataclasses import dataclass
from enum import IntEnum
from typing import Any, List, Dict, Union, Type


# class ConfigItemType(IntEnum):
#
#     Int = 1
#     Float = 2


@dataclass
class ConfigItem:
    """
    配置项
    """
    key:str        ## 关键词
    label:str   ##  标签值，昵称
    default_value:Any    ## 默认值
    desc:str = ''  ## 描述
    _value_type:Type = None

    def __post_init__(self):
        if self._value_type is None:
            if self.default_value is None:
                raise RuntimeError("you must set default_value")
            self._value_type = self.default_value.__class__

    @property
    def value_type(self)->Type:
        return self._value_type

    def get(self,data:{}):
        try:
            return data[self.key]
        except Exception:
            ## 返回设置里面的配置值
            return self.default_value

    def set(self,data:{},value):
        if not isinstance(value,self._value_type):
            raise RuntimeError(f"error type : {value.__class__}, need type: {self._value_type}")
        data[self.key] = value

@dataclass
class ConfigItemOption(ConfigItem):
    """
    枚举类型。
    ConfigItemOption(key = "ss",label="sdf", option_name = ['但是','swwf'],option_values = ['1','2'], defalut_value = '1'
    """
    option_names:List[str] = None  ## 枚举类型。
    option_values:List[Any] = None  ## 枚举类型。

    def __post_init__(self):
        assert self.option_names is not None
        assert len(self.option_names) == len(self.option_values)
        assert self.default_value is not None
        self._value_type = self.option_values[0].__class__

        if not self.option_values.__contains__(self.default_value):
            raise NotImplementedError("defalut_value 设置错误")

    def set(self,data:{},value):
        if not self.option_values.__contains__(value):
            raise NotImplementedError("value 设置错误")
        data[self.key] = value


    def get_option_name(self,value):
        for i in range(0,len(self.option_values)):
            if value == self.option_values[i]:
                return self.option_names[i]
        return None


class Config:
    """
    配置对象。
    """
     ### 对当前项的值

    __slots__ = '_item_list', '_item_map', '_values'

    def __new__(cls,items:List[ConfigItem],values:Dict):
        """
        param：
        items：配置项目
        values: 配置项目值。
        """
        self = object.__new__(cls)
        if values is None:
            values = {}
        self._values = values

        self._item_list = items
        self._item_map = {}
        for item in items:
            self._item_map[item.key] = item
        return self

    def get_items(self)->List[ConfigItem]:
        """
        返回所有的配置项
        :return:
        """
        return self._item_list

    def get_item(self,key:str)->ConfigItem:
        """
        返回某个项目的配置项
        :param name:
        :return:
        """
        return self._item_map[key]

    def get_value(self,key:Union[str,ConfigItem]):
        if isinstance(key,ConfigItem):
            key = key.key
        try:
            return self._values[key]
        except Exception:
            ## 返回设置里面的配置值
            item = self.get_item(key)
            if item is None:
                raise RuntimeError(f"不属于Config的配置项:{key}")
            return item.default_value

    def set_value(self,key:str,value):
        if value is None:
            if self._values.__contains__(key):
                del self._values[key]
            return
        item = self.get_item(key)
        if item is not None:
            item.set(self._values,value)
        else:
            self._values[key] = value

    def to_dict(self):
        return self._values


if __name__ == '__main__':

    ##root_dir = os.path.join(os.path.dirname(__file__),"_app_data_")
    config = ConfigItem(key="sff",label="sdff",default_value=float(3.0))

    _map = {}

    config.set(_map,float(4.3))
    print(f"{config.get(_map)}")
    print(f"{_map}")
    config.set(_map,int(3))